package tzlogin.database;

import org.bukkit.Bukkit;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;

import static tzlogin.database.Connect.hikariDataSource;

public class Manage {
    private static Connection connection;
    private static PreparedStatement preparedStatement;
    private static String command;
    public static final HashMap<String, String> data = new HashMap<>();//玩家密码数据列表(玩家名,密码)
    public static final HashMap<String, List<String>> IP = new HashMap<>();//(IP、该IP下的账号)

    //获得数据库数据
    public void getData() {
        try {
            connection = hikariDataSource.getConnection();
            ResultSet resultSet = connection.createStatement().executeQuery("select * from PlayerPassword");
            while (resultSet.next()) {
                String name = resultSet.getString("Name");
                data.put(name, new String(Base64.getDecoder().decode(resultSet.getString("Password"))));
                String ip = resultSet.getString("IP");
                if (!IP.containsKey(ip)) {
                    List<String> list = new ArrayList<>();
                    list.add(name);
                    IP.put(ip, list);
                } else IP.get(ip).add(name);
            }
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    //向数据库添加数据
    public static void INSERT(String PlayerName, String PlayerPassword) {
        data.put(PlayerName, PlayerPassword);
        String ip = getIP(PlayerName);
        if (!IP.containsKey(ip)) {
            List<String> list = new ArrayList<>();
            list.add(PlayerName);
            IP.put(ip, list);
        } else IP.get(ip).add(PlayerName);
        try {
            connection = hikariDataSource.getConnection();
            command = "insert into PlayerPassword (Name,Password,IP) values(?,?,?)";
            preparedStatement = connection.prepareStatement(command);
            preparedStatement.setString(1, PlayerName);
            preparedStatement.setString(2, Base64.getEncoder().encodeToString(PlayerPassword.getBytes()));
            preparedStatement.setString(3, getIP(PlayerName));
            CloseConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    //更新数据库密码
    public static void UPDATE(String PlayerName, String PlayerPassword) {
        data.replace(PlayerName, PlayerPassword);
        try {
            connection = hikariDataSource.getConnection();
            command = "update PlayerPassword set Password = ? where Name = ?";
            preparedStatement = connection.prepareStatement(command);
            preparedStatement.setString(1, Base64.getEncoder().encodeToString(PlayerPassword.getBytes()));
            preparedStatement.setString(2, PlayerName);
            CloseConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    //删除玩家账号数据
    public static void DELETE(String PlayerName) {
        data.remove(PlayerName);
        String ip = getIP(PlayerName);
        if (IP.get(ip).size() == 0) {
            IP.remove(ip);
        } else IP.get(ip).remove(PlayerName);
        try {
            connection = hikariDataSource.getConnection();
            command = "delete from PlayerPassword where Name = ?";
            preparedStatement = connection.prepareStatement(command);
            preparedStatement.setString(1, PlayerName);
            CloseConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    //关闭数据库连接
    private static void CloseConnection() {
        try {
            preparedStatement.executeUpdate();
            preparedStatement.close();
            connection.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public static String getIP(String PlayerName) {
        String IP = Bukkit.getPlayer(PlayerName).getAddress().toString();
        return IP.substring(1, IP.indexOf(":"));
    }
}
